package com.xhwl.logistics.converter.mapstruct;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.xhwl.logistics.bo.manipulate.VehicleSyncBO;
import com.xhwl.logistics.constant.VehicleConstant;
import com.xhwl.logistics.dto.http.*;
import com.xhwl.logistics.dto.http.query.QueryRoadwayHaiKangDTO;
import com.xhwl.logistics.dto.manipulate.VehicleSyncDTO;
import com.xhwl.logistics.entity.VehicleArea;
import com.xhwl.logistics.entity.VehicleCar;
import com.xhwl.logistics.entity.VehicleCard;
import com.xhwl.logistics.entity.VehicleParkingLot;
import com.xhwl.logistics.entity.VehiclePassage;
import com.xhwl.logistics.enums.VehicleCardTypeEnum;
import com.xhwl.logistics.enums.VehicleRechargeTypeEnum;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.NullValueMappingStrategy;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Mapper(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, uses = {VehicleCommonConverter.class})
public interface VehicleSyncConverter {

    VehicleSyncBO vehicleSyncDTO2VehicleSyncBO(VehicleSyncDTO vehicleSyncDTO);

    @Mapping(source = "parkingLotInfoHaiKangDTO.parkName", target = "parkingLotName")
    @Mapping(source = "parkingLotInfoHaiKangDTO.parkIndexCode", target = "parkId")
    VehicleParkingLot toVehicleParkingLot(ParkingLotInfoHaiKangDTO parkingLotInfoHaiKangDTO, Integer projectId);

    @Mapping(source = "parkingLotInfoJieShunDTO.parkName", target = "parkingLotName")
    @Mapping(source = "parkingLotInfoJieShunDTO.totalSpace", target = "carportTotalNumber")
    @Mapping(source = "parkingLotInfoJieShunDTO.parkCode", target = "parkId")
    VehicleParkingLot toVehicleParkingLot(ParkingLotInfoJieShunDTO parkingLotInfoJieShunDTO, Integer projectId);

    @Mapping(source = "parkingLotInfoHaiKangDTO.parkName", target = "areaName")
    @Mapping(source = "parkingLotInfoHaiKangDTO.parkIndexCode", target = "indexCode")
    VehicleArea toVehicleArea(ParkingLotInfoHaiKangDTO parkingLotInfoHaiKangDTO, Integer parkingLotId, Integer carportTotalNumber);

    @Mapping(source = "parkingLotInfoHaiKangDTO.parkName", target = "passageName")
    @Mapping(source = "roadwayType", target = "type")
    VehiclePassage toVehiclePassage(ParkingLotInfoHaiKangDTO parkingLotInfoHaiKangDTO, Integer areaId, Integer roadwayType);

    default QueryRoadwayHaiKangDTO toEntranceIndexCodesString(List<ParkingLotInfoHaiKangDTO> parkingLotInfoHaiKangDTOList) {
//        String joinString = Joiner.on(',').join(parkingLotInfoHaiKangDTOList.stream()
//                .map(ParkingLotInfoHaiKangDTO::getParkIndexCode)
//                .collect(Collectors.toList()));

        String joinString = parkingLotInfoHaiKangDTOList.stream()
                .map(ParkingLotInfoHaiKangDTO::getParkIndexCode)
                .collect(Collectors.joining(","));

        return new QueryRoadwayHaiKangDTO(joinString);
    }


    //*********Sync KeTop*********
    //*********车场*********
    @Mapping(target = "parkingLotName", source = "parkingLotInfoKeTopDTO.parkName")
    @Mapping(target = "carportTotalNumber", source = "parkingLotInfoKeTopDTO.totalSpaceNum")
    VehicleParkingLot toVehicleParkingLotForAdd(ParkingLotInfoKeTopDTO parkingLotInfoKeTopDTO, Integer projectId);

//    @Mapping(target = "parkingLotName", source = "parkingLotInfoKeTopDTO.parkName")
    @Mapping(target = "carportTotalNumber", source = "parkingLotInfoKeTopDTO.totalSpaceNum")
    @Mapping(target = "parkId", ignore = true)
    VehicleParkingLot toVehicleParkingLotForUpdate(ParkingLotInfoKeTopDTO parkingLotInfoKeTopDTO, Integer id);
    //*********车场*********


    //*********区域*********
    default List<VehicleArea> toVehicleAreaListForAdd(List<ParkingLotAreaInfoKeTopDTO> parkingLotAreaInfoKeTopDTOList, Integer parkingLotId, String parkId) {
        return parkingLotAreaInfoKeTopDTOList.stream()
                .map(parkingLotAreaInfoKeTopDTO -> toVehicleAreaForAdd(parkingLotAreaInfoKeTopDTO, parkingLotId, parkId))
                .collect(Collectors.toList());
    }
    @Mapping(target = "carportTotalNumber", source = "parkingLotAreaInfoKeTopDTO.placeCount")
    @Mapping(target = "thirdAreaId", expression = "java(toThirdAreaId(parkingLotAreaInfoKeTopDTO, parkId))")
    VehicleArea toVehicleAreaForAdd(ParkingLotAreaInfoKeTopDTO parkingLotAreaInfoKeTopDTO, Integer parkingLotId, String parkId);
    default String toThirdAreaId(ParkingLotAreaInfoKeTopDTO parkingLotAreaInfoKeTopDTO, String parkId) {
        return parkId + "-" + parkingLotAreaInfoKeTopDTO.getAreaCode();
    }

    @Mapping(target = "carportTotalNumber", source = "parkingLotAreaInfoKeTopDTO.placeCount")
    VehicleArea toVehicleAreaForUpdate(ParkingLotAreaInfoKeTopDTO parkingLotAreaInfoKeTopDTO, Integer id);
    //*********区域*********


    //*********通道*********
    @Mapping(target = "id", ignore = true)
    @Mapping(target = "passageName", source = "parkingLotPassageInfoKeTopDTO.nodeName")
    @Mapping(target = "type", expression = "java(com.xhwl.logistics.enums.VehiclePassageTypeEnum.toVehiclePassageTypeEnumByKeTop(parkingLotPassageInfoKeTopDTO.getUseType()).getId())")
    @Mapping(target = "thirdPassageId", expression = "java(toPassageThirdId(parkingLotPassageInfoKeTopDTO, areaThirdId))")
    @Mapping(target = "remark", source = "parkingLotPassageInfoKeTopDTO.nodeIp")
    VehiclePassage toVehiclePassageForAdd(ParkingLotPassageInfoKeTopDTO parkingLotPassageInfoKeTopDTO, Integer areaId, String areaThirdId,Integer projectId);
    default String toPassageThirdId(ParkingLotPassageInfoKeTopDTO parkingLotPassageInfoKeTopDTO, String areaThirdId) {
        return areaThirdId + "-" + parkingLotPassageInfoKeTopDTO.getId();
    }

    @Mapping(target = "id", source = "id")
    @Mapping(target = "passageName", source = "parkingLotPassageInfoKeTopDTO.nodeName")
    @Mapping(target = "remark",source = "parkingLotPassageInfoKeTopDTO.nodeIp")
    VehiclePassage toVehiclePassageForUpdate(ParkingLotPassageInfoKeTopDTO parkingLotPassageInfoKeTopDTO, Integer id,Integer projectId);
    //*********通道*********


    //*********车辆列表*********
    default String carListInfoKeTopDTO2PlateNumber(CarListInfoKeTopDTO carListInfoKeTopDTO) {
        JSONArray jsonArrayForPlateNumber = JSON.parseArray(carListInfoKeTopDTO.getPlateNoInfo());
        return jsonArrayForPlateNumber.getJSONObject(0).getString("plateNo");
    }
    default List<VehicleCar> toVehicleCarList(List<CarListInfoKeTopDTO> carListInfoKeTopDTOList, Integer projectId, String projectName, Integer parkingLotId, String parkingLotName) {
        return carListInfoKeTopDTOList.stream()
                .map(carListInfoKeTopDTO -> toVehicleCar(carListInfoKeTopDTO, projectId, projectName, parkingLotId, parkingLotName))
                .collect(Collectors.toList());
    }
    default List<VehicleCar> NanToutoVehicleCarList(List<CarNanTouDTO> carNanTouDTOList,Integer projectId, String projectName, Integer parkingLotId, String parkingLotName){
        return carNanTouDTOList.stream()
                .map(carNanTouDTO -> toVehicleCar(carNanTouDTO,projectId,projectName,parkingLotId,parkingLotName))
                .collect(Collectors.toList());
    }
    default VehicleCar toVehicleCar(CarNanTouDTO carNanTouDTO, Integer projectId, String projectName, Integer parkingLotId, String parkingLotName){
        VehicleCar vehicleCar = new VehicleCar();
        vehicleCar.setProjectId(projectId);
        vehicleCar.setProjectName(projectName);
        vehicleCar.setParkingLotId(parkingLotId);
        vehicleCar.setParkingLotName(parkingLotName);
        vehicleCar.setPlateNumber(carNanTouDTO.getPlateNumber());
        vehicleCar.setCarColor(carNanTouDTO.getCarColor());
        vehicleCar.setOwnerName(carNanTouDTO.getOwnerName());
        vehicleCar.setOwnerPhone(carNanTouDTO.getOwnerPhone());
        vehicleCar.setCardType(carNanTouDTO.getCardType());
        vehicleCar.setCreatorAccountName("xxl-job");
        return vehicleCar;
    }
    default VehicleCar toVehicleCar(CarListInfoKeTopDTO carListInfoKeTopDTO, Integer projectId, String projectName, Integer parkingLotId, String parkingLotName) {
        VehicleCar vehicleCar = new VehicleCar();
        vehicleCar.setProjectId(projectId);
        vehicleCar.setProjectName(projectName);
        vehicleCar.setParkingLotId(parkingLotId);
        vehicleCar.setParkingLotName(parkingLotName);

        vehicleCar.setPlateNumber(carListInfoKeTopDTO2PlateNumber(carListInfoKeTopDTO));

        JSONArray jsonArrayForCardType = JSON.parseArray(carListInfoKeTopDTO.getCarLotList());
        Integer cardType = jsonArrayForCardType.getJSONObject(0).getInteger("carType");
        vehicleCar.setCardType(VehicleCardTypeEnum.toVehicleCardTypeEnumByKeTop(cardType).getId());

        vehicleCar.setOwnerName(carListInfoKeTopDTO.getUseName());
        vehicleCar.setOwnerPhone(carListInfoKeTopDTO.getTel());

        vehicleCar.setCreatorAccountName("xxl-job");

        return vehicleCar;
    }
    //*********车辆列表*********


    //*********车卡充值规则*********
    default String toChargeRule(Integer rechargeMoney,
                               Integer rechargeAmount, Integer rechargeType,
                               Integer freeRechargeAmount, Integer freeRechargeType) {
        StringBuilder init = new StringBuilder("充值金额：");

        BigDecimal divisor = new BigDecimal(100);
        int scale = 2;
        BigDecimal divide = new BigDecimal(rechargeMoney).divide(divisor, scale, VehicleConstant.VEHICLE_PAY_RECORD_ROUNDING_MODE);
        init.append(String.format("%.2f", divide)).append("元");

        init.append("，充值：");

        VehicleRechargeTypeEnum rechargeTypeEnum = VehicleRechargeTypeEnum.toVehicleRechargeTypeEnum(rechargeType);
        if (VehicleRechargeTypeEnum.MONEY == rechargeTypeEnum) {
            BigDecimal divideRechargeAmount = new BigDecimal(rechargeAmount).divide(divisor, scale, VehicleConstant.VEHICLE_PAY_RECORD_ROUNDING_MODE);
            init.append(String.format("%.2f", divideRechargeAmount)).append("元");
        } else {
            init.append(rechargeAmount).append(rechargeTypeEnum.getDescription());
        }

        init.append("，");

        if (freeRechargeAmount.equals(0)) {
            init.append("无赠送");
        } else {
            init.append("赠送：");
            VehicleRechargeTypeEnum freeRechargeTypeEnum = VehicleRechargeTypeEnum.toVehicleRechargeTypeEnum(freeRechargeType);
            if (VehicleRechargeTypeEnum.MONEY == freeRechargeTypeEnum) {
                BigDecimal divideFreeRechargeAmount = new BigDecimal(freeRechargeAmount).divide(divisor, scale, VehicleConstant.VEHICLE_PAY_RECORD_ROUNDING_MODE);
                init.append(String.format("%.2f", divideFreeRechargeAmount)).append("元");
            } else {
                init.append(freeRechargeAmount).append(freeRechargeTypeEnum.getDescription());
            }
        }

        return init.toString();
    }


    default List<VehicleCard> toVehicleCardList(List<CardRuleInfoKeTopDTO> cardRuleInfoKeTopDTOList, Integer keTopCardType, Integer projectId, String projectName, Integer parkingLotId, String parkingLotName) {
        return cardRuleInfoKeTopDTOList.stream()
                .map(cardRuleInfoKeTopDTO -> toVehicleCard(cardRuleInfoKeTopDTO, keTopCardType, projectId, projectName, parkingLotId, parkingLotName))
                .collect(Collectors.toList());
    }
    @Mapping(target = "name", source = "cardRuleInfoKeTopDTO.ruleName")
    @Mapping(target = "cardType", source = "keTopCardType", qualifiedByName = {"keTopCardTypeId2VehicleCardTypeId"})
    @Mapping(target = "rechargeType", source = "cardRuleInfoKeTopDTO.rechargeType", qualifiedByName = {"keTopRechargeTypeId2VehicleRechargeTypeId"})
    @Mapping(target = "freeRechargeType", source = "cardRuleInfoKeTopDTO.sentType", qualifiedByName = {"keTopRechargeTypeId2VehicleRechargeTypeId"})
    @Mapping(target = "freeRechargeAmount", source = "cardRuleInfoKeTopDTO.sentAmount")
    @Mapping(target = "rechargeMoney", source = "cardRuleInfoKeTopDTO.basicMoney")
    @Mapping(target = "thirdRuleId", source = "cardRuleInfoKeTopDTO.ruleId")
    VehicleCard toVehicleCard(CardRuleInfoKeTopDTO cardRuleInfoKeTopDTO, Integer keTopCardType, Integer projectId, String projectName, Integer parkingLotId, String parkingLotName);
    default VehicleCard toVehicleCard(VehicleCard vehicleCard, String creatorAccountName) {
        vehicleCard.setCreatorAccountName(creatorAccountName);

        vehicleCard.setChargeRule(toChargeRule(vehicleCard.getRechargeMoney(),
                vehicleCard.getRechargeAmount(), vehicleCard.getRechargeType(),
                vehicleCard.getFreeRechargeAmount(), vehicleCard.getFreeRechargeType()));

        return vehicleCard;
    }


    default VehicleCard toVehicleCardForUpdate(VehicleCard vehicleCardForUpdate, Integer id) {
        VehicleCard vehicleCard = new VehicleCard();
        vehicleCard.setId(id);

        vehicleCard.setName(vehicleCardForUpdate.getName());
        vehicleCard.setChargeRule(toChargeRule(vehicleCardForUpdate.getRechargeMoney(),
                vehicleCardForUpdate.getRechargeAmount(), vehicleCardForUpdate.getRechargeType(),
                vehicleCardForUpdate.getFreeRechargeAmount(), vehicleCardForUpdate.getFreeRechargeType()));
        vehicleCard.setCardType(vehicleCardForUpdate.getCardType());

        vehicleCard.setRechargeType(vehicleCardForUpdate.getRechargeType());
        vehicleCard.setRechargeAmount(vehicleCardForUpdate.getRechargeAmount());
        vehicleCard.setFreeRechargeType(vehicleCardForUpdate.getFreeRechargeType());
        vehicleCard.setFreeRechargeAmount(vehicleCardForUpdate.getFreeRechargeAmount());
        vehicleCard.setRechargeMoney(vehicleCardForUpdate.getRechargeMoney());

        vehicleCard.setEditorAccountName("xxl-job");

        return vehicleCard;
    }
    //*********车卡充值规则*********

    //*********Sync KeTop*********

    //*********科松车场*********
    @Mapping(target = "parkingLotName", source = "parkingLotInfoCoSonDTO.parkName")
    @Mapping(target = "carportTotalNumber", source = "parkingLotInfoCoSonDTO.spaceTotal")
    default VehicleParkingLot toVehicleParkingLotAddForCoSon(ParkingLotInfoCoSonDTO parkingLotInfoCoSonDTO, Integer projectId){
        VehicleParkingLot vehicleParkingLot = new VehicleParkingLot();
        if ( parkingLotInfoCoSonDTO != null ) {
            vehicleParkingLot.setParkingLotName( parkingLotInfoCoSonDTO.getParkName() );
            vehicleParkingLot.setCarportTotalNumber(Integer.valueOf(parkingLotInfoCoSonDTO.getSpaceTotal()));
            if ( parkingLotInfoCoSonDTO.getParkkey() != null ) {
                vehicleParkingLot.setParkId( String.valueOf( parkingLotInfoCoSonDTO.getParkkey() ) );
            }
        }
        if ( projectId != null ) {
            vehicleParkingLot.setProjectId( projectId );
        }
        return vehicleParkingLot;
    }
    @Mapping(target = "carportTotalNumber", source = "parkingLotInfoCoSonDTO.spaceTotal")
    @Mapping(target = "parkId", source = "parkingLotInfoCoSonDTO.parkkey")
    default VehicleParkingLot toVehicleParkingLotUpdateForCoSon(ParkingLotInfoCoSonDTO parkingLotInfoCoSonDTO, Integer id){
        VehicleParkingLot vehicleParkingLot = new VehicleParkingLot();
        if ( parkingLotInfoCoSonDTO != null ) {
            vehicleParkingLot.setCarportTotalNumber(Integer.valueOf(parkingLotInfoCoSonDTO.getSpaceTotal()));
        }
        if ( id != null ) {
            vehicleParkingLot.setId( id );
        }
        return vehicleParkingLot;
    }
    //*********科松车场*********


}
